package cn.echo.consul.manager.util;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * KeyValue转换相关类
 */
public class KeyValueUtil {
    private static String profileDot = ".";

    /**
     * 获取并转换KV配置为Map
     */
    public static Map<String, String> getKVConfigs(Map map) {
        Map<String, String> configs = new TreeMap<>();
        if (map==null) {
            return configs;
        }
        for (Object item: map.entrySet()) {
            //取prefix为空或以prefix开头的key
            Map.Entry entry = (Map.Entry) item;
            transKVValue(configs, entry.getKey().toString(), entry.getValue());
        }
        return configs;
    }

    /**
     * 键值类型转换为对象
     */
    private static Object transValue(String value) {
        Object objValue;
        if (value.trim().startsWith("{")) {
            objValue = JsonUtil.fromJson(value, Map.class);
        } else if (value.trim().startsWith("[")) {
            objValue = JsonUtil.fromJson(value, List.class);
        } else if (NumberUtils.isNumber(value)) {
            objValue = NumberUtils.createNumber(value);
        } else {
            objValue = value.trim();
        }
        return objValue;
    }


    /**
     * 根据"."的key进行解析成嵌套的Map ->支持YAML
     * 返回旧值
     */
    public static String change(Map<String, Object> map, String key, String value) {
        //只要有.号,就代表有子map
        String itemValue = "";
        if (key.contains(profileDot)) {
            int index = key.indexOf(profileDot);
            String firstKey = key.substring(0, index);
            String sonKey = key.substring(firstKey.length() + 1);
            //如果为.xxx格式，直接丢弃
            if (StringUtils.isEmpty(firstKey)) {
                return "";
            }
            //继续循环
            Object sonMap = map.get(firstKey);
            //之前没有key或者key非map -> 覆盖
            if (!(sonMap instanceof Map)) {
                sonMap = new TreeMap<>();
                map.put(firstKey, sonMap);
            }
            itemValue = change((Map<String, Object>) sonMap, sonKey, value);
        } else {
            Object oldValue = map.get(key);
            map.put(key, transValue(value));

            if (oldValue!=null) {
                if (oldValue instanceof List) {
                    itemValue = JsonUtil.toJson(oldValue);
                } else {
                    itemValue = oldValue+"";
                }
            }
        }
        return itemValue;
    }

    /**
     * 键值类型转换
     */
    private static void transKVValue(Map<String, String> configs, String key, Object value) {
        if (value instanceof Map) {
            Map<String, Object> tmp = (Map)value;
            if (tmp.size()==0) {
                configs.put(key, JsonUtil.toJson(value));
                return;
            }
            for (Map.Entry<String, Object> entry: tmp.entrySet()) {
                transKVValue(configs, key + profileDot + entry.getKey(), entry.getValue());
            }
        } else if (value instanceof List) {
            configs.put(key, JsonUtil.toJson(value));
        } else {
            configs.put(key, value==null? "": value.toString());
        }
    }
}
